home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
4_0
/
UNZIP102
/
UNZIP.C
< prev
next >
Wrap
Text File
|
1990-07-14
|
44KB
|
1,932 lines
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*
* UnZip - A ZIP file extract utility for ZIP files and ZIP ".EXE" files
* archived using PKZIP 1.10 or earlier. Recognizes and dearchives ╥stored╙,
* ╥shrunk╙, ╥reduced╙ and ╥imploded╙ files.
*
* VERSION: UnZip 1.02c ╤ July 14, 1990
*
* Translated into Lightspeed C v.4.0 and adapted for the Mac by A.P. Maika,
* (utilizing TransSkel 2.01 and TransDisplay 2.0 written by Paul DuBois)
*
* Dearchiving code for ╥extracting╙, ╥unshrinking╙, and ╥expanding╙ written
* in Turbo C v. 2.0 ⌐ Samuel H. Smith (version 1.2 of 03-15-89)
* Adapted for the Atari ST and CRC inline assembly code ⌐ Darin Wayrynen
*
* Dearchiving code for ╥exploding╙ derived from Turbo Pascal v. 5.0
* source ⌐ R.P. Byrne (version 2.0 of 07-31-89)
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*
* Host operating system details
*/
#include <string.h>
#include <stdlib.h>
#include <unix.h>
#include <fcntl.h>
#include <TransDisplay.h>
#define HIGH_LOW 1
MenuHandle mFile,mOptions,mfilter,mstrip;
CursHandle c;
WindowRecord wprogressRec;
WindowPtr wlist,wprogress;
Point bloc = {40,40};
Rect prect;
SFReply SFzipfd;
FInfo ffinfo;
Boolean finishedflag,dirflag;
Boolean stripLFflag=false;
Boolean wlistflag=false;
Boolean choosefileflag=false;
Boolean TEXTfilterflag=false;
char tstring[256],tfilename[256];
long zipoffset[100],progresscount,sizeblock,fpos;
int direntries,dindex,blockcount,numblocks;
typedef struct gifinfo
{
char gif_signature[6];
int screen_width;
int screen_height;
char color_resolution;
} gifinfo;
/* -------------------------------------------------------------------------- */
/* stuff needed for exploding */
#define LITERAL_TREE_ROOT 256
#define DISTANCE_TREE_ROOT 64
#define LENGTH_TREE_ROOT 64
typedef struct SF_Node
{
int LChild;
int RChild;
} SF_Node;
SF_Node SF_Literal[LITERAL_TREE_ROOT + 1];
SF_Node SF_Distance[DISTANCE_TREE_ROOT + 1];;
SF_Node SF_Length[LENGTH_TREE_ROOT + 1];
typedef struct SF_BuildRec
{
int Len;
int Val;
int Code;
} SF_BuildRec;
int NextFreeLiteral;
int NextFreeLength;
int NextFreeDistance;
int NumOfTrees;
int MinMatchLen;
int DictSize;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*
* dearchiving code Copyright 1989 Samuel H. Smith; All rights reserved
*
* Do not distribute modified versions without my permission.
* Do not remove or alter this notice or any other copyright notice.
* If you use this in your own program you must distribute source code.
* Do not use any of this in a commercial product.
*
*/
#define CODE_VERSION "UnZip: Zipfile Extract v1.2 of 03-15-89; (C) 1989 Samuel H. Smith"
typedef unsigned char byte; /* code assumes UNSIGNED bytes */
typedef long longint;
typedef unsigned word;
typedef char boolean;
#define STRSIZ 256
unsigned int in_size,out_size;
/* -------------------------------------------------------------------------- */
/*
* Zipfile layout declarations
*/
typedef longint signature_type;
#define LOCAL_FILE_HEADER_SIGNATURE 0x504B0304L
typedef struct local_file_header {
word version_needed_to_extract;
word general_purpose_bit_flag;
int compression_method;
int last_mod_file_time;
int last_mod_file_date;
longint crc32;
longint compressed_size;
longint uncompressed_size;
int filename_length;
int extra_field_length;
} local_file_header;
#define CENTRAL_FILE_HEADER_SIGNATURE 0x504B0102L
typedef struct central_directory_file_header {
word version_made_by;
word version_needed_to_extract;
word general_purpose_bit_flag;
word compression_method;
word last_mod_file_time;
word last_mod_file_date;
longint crc32;
longint compressed_size;
longint uncompressed_size;
word filename_length;
word extra_field_length;
word file_comment_length;
word disk_number_start;
word internal_file_attributes;
longint external_file_attributes;
longint relative_offset_local_header;
} central_directory_file_header;
#define END_CENTRAL_DIR_SIGNATURE 0x504B0506L
typedef struct end_central_dir_record {
word number_this_disk;
word number_disk_with_start_central_directory;
word total_entries_central_dir_on_this_disk;
word total_entries_central_dir;
longint size_central_directory;
longint offset_start_central_directory;
word zipfile_comment_length;
} end_central_dir_record;
/* -------------------------------------------------------------------------- */
/*
* input file variables
*
*/
#define INBUFSIZ 0x2000L
char *inbuf; /* input file buffer - any size is legal */
char *inptr;
int incnt;
unsigned bitbuf;
int bits_left;
boolean zipeof;
int zipfd;
local_file_header lrec;
/* -------------------------------------------------------------------------- */
/*
* output stream variables
*
*/
#define OUTBUFSIZ 0x6000L
char *outbuf; /* buffer for rle look-back */
char *outptr;
long outpos; /* absolute position in outfile */
unsigned int outcnt; /* current position in outbuf */
int outfd;
char filename[STRSIZ];
char extra[STRSIZ];
#define DLE 144
/* -------------------------------------------------------------------------- */
/*
* shrink/reduce working storage
*
*/
int factor;
byte followers[256][64];
byte Slen[256];
#define max_bits 13
#define init_bits 9
#define hsize 8192
#define first_ent 257
#define clear 256
int *Prefix_of;
byte *Suffix_of;
byte *Stack;
int codesize;
int maxcode;
int free_ent;
int maxcodemax;
int offset;
int sizex;
/* -------------------------------------------------------------------------- */
void swap_bytes(wordp)
word *wordp;
/* convert intel style ╘short int╒ variable to host format */
{
char *charp = (char *) wordp;
char temp;
temp = charp[0];
charp[0] = charp[1];
charp[1] = temp;
}
/* -------------------------------------------------------------------------- */
void swap_lbytes(longp)
longint *longp;
/* convert intel style ╘long╒ variable to host format */
{
char *charp = (char *) longp;
char temp[4];
temp[3] = charp[0];
temp[2] = charp[1];
temp[1] = charp[2];
temp[0] = charp[3];
charp[0] = temp[0];
charp[1] = temp[1];
charp[2] = temp[2];
charp[3] = temp[3];
}
/* -------------------------------------------------------------------------- */
int FillBuffer()
/* fill input buffer if possible */
{
extern local_file_header lrec;
unsigned int readsize;
if (lrec.compressed_size <= 0 ) return (incnt = 0);
if (lrec.compressed_size > (long) in_size) readsize = in_size;
else readsize = (int) lrec.compressed_size;
incnt = read(zipfd, inbuf, readsize);
lrec.compressed_size -= incnt;
inptr = inbuf;
return (incnt--);
}
/* -------------------------------------------------------------------------- */
int ReadByte(x)
unsigned *x;
/* read a byte; return 8 if byte available, 0 if not */
{
/* counter for UpdateProgressWind */
if(sizeblock == ++progresscount)
{
progresscount = 0L;
UpdateProgressWind(numblocks,++blockcount);
}
if (incnt-- == 0)
if (FillBuffer() == 0)
return 0;
*x = *inptr++;
return 8;
}
/* -------------------------------------------------------------------------- */
static unsigned mask_bits[] =
{0, 0x0001, 0x0003, 0x0007, 0x000f,
0x001f, 0x003f, 0x007f, 0x00ff,
0x01ff, 0x03ff, 0x07ff, 0x0fff,
0x1fff, 0x3fff, 0x7fff, 0xffff
};
/* -------------------------------------------------------------------------- */
int FillBitBuffer(bits)
register int bits;
{
/* get the bits that are left and read the next word */
unsigned temp;
register int result = bitbuf;
int sbits = bits_left;
bits -= bits_left;
/* read next word of input */
bits_left = ReadByte(&bitbuf);
bitbuf = bitbuf & 0x00FF;
bits_left += ReadByte(&temp);
bitbuf |= (temp << 8);
if (bits_left == 0)
zipeof = 1;
/* get the remaining bits */
result = result | (int) ((bitbuf & mask_bits[bits]) << sbits);
bitbuf >>= bits;
bits_left -= bits;
return result;
}
/* -------------------------------------------------------------------------- */
#define READBIT(nbits,zdest) { if (nbits <= bits_left) { zdest = (int)(bitbuf & mask_bits[nbits]); bitbuf >>= nbits; bits_left -= nbits; } else zdest = FillBitBuffer(nbits);}
/*
* macro READBIT(nbits,zdest)
* {
* if (nbits <= bits_left) {
* zdest = (int)(bitbuf & mask_bits[nbits]);
* bitbuf >>= nbits;
* bits_left -= nbits;
* } else
* zdest = FillBitBuffer(nbits);
* }
*
*/
/* -------------------------------------------------------------------------- */
#include "crc32.h"
/* -------------------------------------------------------------------------- */
void FlushOutput()
/* flush contents of output buffer */
{
UpdateCRC(outbuf, outcnt);
write(outfd, outbuf, outcnt);
outpos = outpos + (long) outcnt;
outcnt = 0;
outptr = outbuf;
}
/* -------------------------------------------------------------------------- */
#define OUTB(intc) { *outptr++=intc; if (++outcnt==out_size) FlushOutput(); }
/*
* macro OUTB(intc)
* {
* *outptr++=intc;
* if (++outcnt==out_size)
* FlushOutput();
* }
*
*/
/* -------------------------------------------------------------------------- */
void LoadFollowers()
{
register int x;
register int i;
for (x = 255; x >= 0; x--)
{
READBIT(6,Slen[x]);
for (i = 0; i < Slen[x]; i++)
{
READBIT(8,followers[x][i]);
}
}
}
/* -------------------------------------------------------------------------- */
/*
* The Reducing algorithm is actually a combination of two
* distinct algorithms. The first algorithm compresses repeated
* byte sequences, and the second algorithm takes the compressed
* stream from the first algorithm and applies a probabilistic
* compression method.
*/
int L_table[] = {0, 0x7f, 0x3f, 0x1f, 0x0f};
int D_shift[] = {0, 0x07, 0x06, 0x05, 0x04};
int D_mask[] = {0, 0x01, 0x03, 0x07, 0x0f};
int B_table[] = {8, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8};
/* -------------------------------------------------------------------------- */
void unReduce()
/* expand probablisticly reduced data */
{
register int lchar;
register int nchar;
int ExState;
register int V;
register int Len;
int ix,i,offset;
long op;
factor = lrec.compression_method - 1;
ExState = 0;
lchar = 0;
LoadFollowers();
while (((outpos + outcnt) < lrec.uncompressed_size) && (!zipeof))
{
if (Slen[lchar] == 0) READBIT(8,nchar) /* ; */
else
{
READBIT(1,nchar);
if (nchar != 0) READBIT(8,nchar) /* ; */
else
{
int follower;
int bitsneeded = B_table[Slen[lchar]];
READBIT(bitsneeded,follower);
nchar = followers[lchar][follower];
}
}
/* expand the resulting byte */
switch (ExState)
{
case 0:
if (nchar != DLE) OUTB(nchar) /* ; */
else
ExState = 1;
break;
case 1:
if (nchar != 0)
{
V = nchar;
Len = V & L_table[factor];
if (Len == L_table[factor]) ExState = 2;
else ExState = 3;
}
else
{
OUTB(DLE);
ExState = 0;
}
break;
case 2:
{
Len += nchar;
ExState = 3;
}
break;
case 3:
{
i = Len + 3;
offset = (((V >> D_shift[factor]) &
D_mask[factor]) << 8) + nchar + 1;
op = outpos + outcnt - offset;
/* special case- before start of file */
while ((op < 0L) && (i > 0))
{
OUTB(0);
op++;
i--;
}
/* normal copy of data from output buffer */
{
ix = (int) (op % out_size);
/* do a block memory copy if possible */
if ( ((ix +i) < out_size) && ((outcnt+i) < out_size) )
{
memcpy(outptr,&outbuf[ix],i);
outptr += i;
outcnt += i;
}
/* otherwise copy byte by byte */
else while (i--)
{
OUTB(outbuf[ix]);
if (++ix >= out_size) ix = 0;
}
}
ExState = 0;
}
break;
}
/* store character for next iteration */
lchar = nchar;
}
}
/* -------------------------------------------------------------------------- */
/*
* Shrinking is a Dynamic Ziv-Lempel-Welch compression algorithm
* with partial clearing.
*
*/
void partial_clear()
{
extern int *Prefix_of;
register int pr;
register int cd;
/* mark all nodes as potentially unused */
for (cd = first_ent; cd < free_ent; cd++)
*(Prefix_of + cd) |= 0x8000;
/* unmark those that are used by other nodes */
for (cd = first_ent; cd < free_ent; cd++) {
pr = *(Prefix_of + cd) & 0x7fff; /* reference to another node? */
if (pr >= first_ent) /* flag node as referenced */
*(Prefix_of +pr) &= 0x7fff;
}
/* clear the ones that are still marked */
for (cd = first_ent; cd < free_ent; cd++)
if ((*(Prefix_of + cd) & 0x8000) != 0)
*(Prefix_of + cd) = -1;
/* find first cleared node as next free_ent */
cd = first_ent;
while ((cd < maxcodemax) && (*(Prefix_of + cd) != -1))
cd++;
free_ent = cd;
}
/* -------------------------------------------------------------------------- */
void unShrink()
{
#define GetCode(dest) READBIT(codesize,dest)
extern int *Prefix_of;
extern byte *Suffix_of;
extern local_file_header lrec;
extern byte *Stack;
register int code;
register int stackp;
int finchar;
int oldcode;
int incode;
void partial_clear();
/* decompress the file */
maxcodemax = 1 << max_bits;
codesize = init_bits;
maxcode = (1 << codesize) - 1;
free_ent = first_ent;
offset = 0;
sizex = 0;
for (code = maxcodemax; code > 255; code--)
*(Prefix_of + code) = -1;
for (code = 255; code >= 0; code--)
{
*(Prefix_of + code) = 0;
*(Suffix_of + code) = code;
}
GetCode(oldcode);
if (zipeof) return;
finchar = oldcode;
OUTB(finchar);
stackp = hsize;
while (!zipeof)
{
GetCode(code);
if (zipeof) return;
while (code == clear)
{
GetCode(code);
switch (code)
{
case 1:
{
codesize++;
if (codesize == max_bits)
maxcode = maxcodemax;
else
maxcode = (1 << codesize) - 1;
}
break;
case 2:
partial_clear();
break;
}
GetCode(code);
if (zipeof) return;
}
/* special case for KwKwK string */
incode = code;
if (*(Prefix_of + code) == -1)
{
*(Stack + --stackp) = finchar;
code = oldcode;
}
/* generate output characters in reverse order */
while (code >= first_ent)
{
*(Stack + --stackp) = *(Suffix_of + code);
code = *(Prefix_of + code);
}
finchar = *(Suffix_of + code);
*(Stack + --stackp) = finchar;
/* and put them out in forward order, block copy */
if ((hsize-stackp+outcnt) < out_size)
{
memcpy(outptr,Stack+stackp,hsize-stackp);
outptr += hsize-stackp;
outcnt += hsize-stackp;
stackp = hsize;
}
/* output byte by byte if we can╒t go by blocks */
else while (stackp < hsize)
OUTB(*(Stack + stackp++));
/* generate new entry */
code = free_ent;
if (code < maxcodemax)
{
*(Prefix_of + code) = oldcode;
*(Suffix_of + code) = finchar;
do
code++;
while ((code < maxcodemax) && (*(Prefix_of + code) != -1));
free_ent = code;
}
/* remember previous code */
oldcode = incode;
}
}
/* ------------------------------------------------------------------------- */
void get_string(len,s)
int len;
char *s;
{
read(zipfd, s, len);
s[len] = 0;
}
/* ------------------------------------------------------------------------- */
/*memcpy(to,from,count)
register char *to,*from;
register unsigned int count;
{
for(;count>0;--count,++to,++from)
*to=*from;
}*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*
* Exploding code derived from Turbo Pascal v. 5.0 source ⌐ R.P. Byrne
* (version 2.0 ╤ July 31, 1989)
*
*/
/* -------------------------------------------------------------------------- */
Bad_SF_Tree()
{
close(outfd);
CloseProgressWind();
DisplayString("\p -- bad Shannon-Fano decode tree -- file skipped\015");
}
/* -------------------------------------------------------------------------- */
Boolean Add_SF_SubTree(SF_TreePtr,SF_NextFreePtr,CurrNode,SF_Code,SF_Len,SF_Val)
SF_Node (*SF_TreePtr)[];
int *SF_NextFreePtr;
int CurrNode;
int SF_Code;
int SF_Len;
int SF_Val;
{
int i;
for (i=(SF_Len - 1); i>=1; i--)
{
if (0 >= CurrNode)
{
Bad_SF_Tree();
return(true);
}
if ((SF_Code >> i) & 0x0001)
{
if (-999 == (*SF_TreePtr)[CurrNode].RChild)
{
(*SF_TreePtr)[CurrNode].RChild = *SF_NextFreePtr;
(*SF_NextFreePtr)--;
}
CurrNode = (*SF_TreePtr)[CurrNode].RChild;
}
else
{
if (-999 == (*SF_TreePtr)[CurrNode].LChild)
{
(*SF_TreePtr)[CurrNode].LChild = *SF_NextFreePtr;
(*SF_NextFreePtr)--;
}
CurrNode = (*SF_TreePtr)[CurrNode].LChild;
}
}
if (SF_Code & 0x0001)
{
if (-999 != (*SF_TreePtr)[CurrNode].RChild)
{
Bad_SF_Tree();
return(true);
}
else (*SF_TreePtr)[CurrNode].RChild = -SF_Val;
}
else
{
if (-999 != (*SF_TreePtr)[CurrNode].LChild)
{
Bad_SF_Tree();
return(true);
}
else (*SF_TreePtr)[CurrNode].LChild = -SF_Val;
}
return (false);
}
/* -------------------------------------------------------------------------- */
Boolean Construct_SF_Tree(SF_TreePtr,SF_NextFreePtr,treesize)
SF_Node (*SF_TreePtr)[];
int *SF_NextFreePtr;
int treesize;
{
static int swapsize[]={9,5,3,2,1};
SF_BuildRec SF_Build[256];
SF_BuildRec tempnode;
int OneByte;
char CodeLen;
char CodeCount;
int SF_Table_Codes;
int SF_Build_Idx;
int BuildCount;
unsigned int Code;
unsigned int CodeIncrement;
int LastBitLength;
register int i,j,k,s;
int w,tLen,tVal;
SF_Build_Idx = 0;
BuildCount = 0;
if(0 == ReadByte(&SF_Table_Codes))
{
DisplayString("\p -- unexpected end of file -- file skipped");
return(true);
}
for (i=0; i<=SF_Table_Codes; i++)
{
if(0 == ReadByte(&OneByte))
{
DisplayString("\p -- unexpected end of file -- file skipped");
return(true);
}
CodeLen = (OneByte & 0x000F) + 1;
CodeCount = (OneByte >> 4) & 0x000F;
for (j=0; j<=CodeCount; j++)
{
SF_Build[SF_Build_Idx].Len = CodeLen;
SF_Build[SF_Build_Idx].Val = SF_Build_Idx;
SF_Build_Idx++;
}
}
BuildCount = SF_Build_Idx - 1;
/* Shell sort of tree leaves */
for (w=0; w<5; w++)
{
k = swapsize[w];
s = -k;
for (i=k; i<=BuildCount; ++i)
{
tLen = SF_Build[i].Len;
tVal = SF_Build[i].Val;
j = i - k;
if (s==0)
{
s = -k;
s++;
SF_Build[s].Len = tLen;
SF_Build[s].Val = tVal;
}
while (((tLen < SF_Build[j].Len) ||
((tLen == SF_Build[j].Len) && (tVal < SF_Build[j].Val)))
&& j>=0 && j<=BuildCount+1)
{
SF_Build[j+k].Len = SF_Build[j].Len;
SF_Build[j+k].Val = SF_Build[j].Val;
j = j - k;
}
SF_Build[j+k].Len = tLen;
SF_Build[j+k].Val = tVal;
}
}
Code = 0;
CodeIncrement = 0;
LastBitLength = 0;
for (i=BuildCount; i>=0; i--)
{
Code = Code + CodeIncrement;
if(SF_Build[i].Len != LastBitLength)
{
LastBitLength = SF_Build[i].Len;
CodeIncrement = 1 << (16 - LastBitLength);
}
SF_Build[i].Code = Code >> (16 - SF_Build[i].Len);
/* sprintf(tstring,"\r%3d %3d %3d %4X",i,SF_Build[i].Len,SF_Build[i].Val,SF_Build[i].Code);
DisplayString(CtoPstr(tstring)); */
if(Add_SF_SubTree( SF_TreePtr,
SF_NextFreePtr,
treesize,
SF_Build[i].Code,
SF_Build[i].Len,
SF_Build[i].Val )) return (true);
}
/* for (i=0;i<=treesize;i++)
fprintf(sftrees,"\r%3d %3d %3d",i,(*SF_TreePtr)[i].LChild,(*SF_TreePtr)[i].RChild);
fprintf(sftrees,"\r\r"); */
return (false);
}
/* -------------------------------------------------------------------------- */
Boolean Init_Explode()
{
int i;
DictSize = (((lrec.general_purpose_bit_flag >> 1) & 0x01) * 4096) + 4096;
NumOfTrees = ((lrec.general_purpose_bit_flag >> 2) & 0x01) + 2;
MinMatchLen = NumOfTrees;
for (i=0; i<=LENGTH_TREE_ROOT; i++)
{
SF_Length[i].LChild = -999;
SF_Length[i].RChild = -999;
}
NextFreeLength = LENGTH_TREE_ROOT - 1;
for (i=0; i<=DISTANCE_TREE_ROOT; i++)
{
SF_Distance[i].LChild = -999;
SF_Distance[i].RChild = -999;
}
NextFreeDistance = DISTANCE_TREE_ROOT - 1;
if(3==NumOfTrees)
{
for (i=0; i<=LITERAL_TREE_ROOT; i++)
{
SF_Literal[i].LChild = -999;
SF_Literal[i].RChild = -999;
}
NextFreeLiteral = LITERAL_TREE_ROOT - 1;
if(Construct_SF_Tree(&SF_Literal,&NextFreeLiteral,LITERAL_TREE_ROOT)) return(true);
}
if(Construct_SF_Tree(&SF_Length,&NextFreeLength,LENGTH_TREE_ROOT)) return(true);
if(Construct_SF_Tree(&SF_Distance,&NextFreeDistance,DISTANCE_TREE_ROOT)) return(true);
return (false);
}
/* -------------------------------------------------------------------------- */
Boolean Decode_SF_Data(SF_TreePtr,CurrNode,OutputPtr)
register SF_Node (*SF_TreePtr)[];
register int CurrNode;
int *OutputPtr;
{
register int OneBit;
while (0 < CurrNode)
{
READBIT(1,OneBit);
if (OneBit)
{
if (-999 == (*SF_TreePtr)[CurrNode].RChild)
{
Bad_SF_Tree();
return(true);
}
else CurrNode = (*SF_TreePtr)[CurrNode].RChild;
}
else
{
if (-999 == (*SF_TreePtr)[CurrNode].LChild)
{
Bad_SF_Tree();
return(true);
}
else CurrNode = (*SF_TreePtr)[CurrNode].LChild;
}
}
*OutputPtr = -CurrNode;
return (false);
}
/* -------------------------------------------------------------------------- */
Boolean Explode()
{
extern byte *Stack;
int DistVal;
int Literal;
int Length;
int Distance;
int NBits;
int Mask;
register int StackIdx;
register int StackStart;
register int OneByte;
register int i;
Boolean LiteralTreeflag;
if(Init_Explode()) return;
for (StackIdx=0; StackIdx<hsize+1; StackIdx++) *(Stack + StackIdx) = 0;
StackIdx = 0;
LiteralTreeflag = (3 == NumOfTrees);
if ((8192 == DictSize))
{
NBits = 7;
Mask = 0x1FFF;
}
else
{
NBits = 6;
Mask = 0x0FFF;
}
while ((!zipeof) && ((outpos + outcnt) < lrec.uncompressed_size))
{
READBIT(1,OneByte);
if (OneByte)
{
if(LiteralTreeflag)
{
if(Decode_SF_Data(&SF_Literal,LITERAL_TREE_ROOT,&Literal)) return (true);
}
else READBIT(8,Literal);
OUTB(Literal);
Stack[StackIdx] = (char) Literal;
if(DictSize == ++StackIdx) StackIdx = 0;
}
else
{
READBIT(NBits,Distance);
if(Decode_SF_Data(&SF_Distance,DISTANCE_TREE_ROOT,&DistVal)) return (true);
Distance = (Distance | (DistVal << NBits)) & Mask;
if(Decode_SF_Data(&SF_Length,LENGTH_TREE_ROOT,&Length)) return (true);
if (63 == Length)
{
READBIT(8,i);
Length = Length + i;
}
i = Length + MinMatchLen;
StackStart = StackIdx - (Distance + 1);
if(0 > StackStart) StackStart = StackStart + DictSize;
while (i-- > 0)
{
OUTB(Stack[StackStart]);
Stack[StackIdx] = Stack[StackStart];
if(DictSize == ++StackIdx) StackIdx = 0;
if(DictSize == ++StackStart) StackStart = 0;
}
}
}
return (false);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
OSErr freeSpaceOnVol(vRef,pfreeBytes)
int vRef;
unsigned long *pfreeBytes;
{
HVolumeParam HPB;
OSErr err;
long temp;
HPB.ioNamePtr = 0L;
HPB.ioVRefNum = vRef;
HPB.ioVolIndex = 0;
err = PBHGetVInfo(&HPB,false);
/* modification of July 14, 1990 - UnZip 1.02c to eliminate sign extension
problem with HPB.ioVFrBlk which resulted in a negative number if the
nnumber of free blocks exceeded 32767 */
temp = HPB.ioVFrBlk;
if(0 > temp) temp = 65536L + temp;
if(err==noErr) *pfreeBytes = (unsigned long) temp * HPB.ioVAlBlkSiz;
else *pfreeBytes = 0L;
/* Monitor("HPB.ioVAlBlkSiz",(int) HPB.ioVAlBlkSiz,"HPB.ioVFrBlk",(int) HPB.ioVFrBlk,"temp",temp);*/
return(err);
}
/* ------------------------------------------------------------------------- */
Monitor(s1,v1,s2,v2,s3,v3)
/* debugging routine to monitor variables */
char s1[32],s2[32],s3[32];
int v1,v2;
long v3;
{
char ts1[60],ts2[60],ts3[60];
sprintf(ts1,"%10d %s",v1,s1);
sprintf(ts2,"%10d %s",v2,s2);
sprintf(ts3,"%10ld %s",v3,s3);
ParamText(CtoPstr(ts1),CtoPstr(ts2),CtoPstr(ts3),"\p");
Alert(103,nil);
}
/* -------------------------------------------------------------------------- */
InitProgressWind(dearchivingtype)
char *dearchivingtype;
{
int width;
wprogress = GetNewWindow(102,&wprogressRec,-1L);
SetPort(wprogress);
sprintf(tstring,"%s : %s %ld \304> %ld bytes",
dearchivingtype,
filename,
lrec.compressed_size,
lrec.uncompressed_size);
TextFont(150);
TextSize(9);
TextFace(bold);
width = StringWidth(CtoPstr(tstring));
MoveTo(((416-width)/2),15);
DrawString(tstring);
SetRect(&prect,38,22,380,40);
FrameRect(&prect);
numblocks = 20;
sizeblock = lrec.compressed_size/20L;
if(50000L > lrec.compressed_size)
{
sizeblock = lrec.compressed_size/10L;
numblocks = 10;
}
if(10000L > lrec.compressed_size)
{
sizeblock = lrec.compressed_size/4L;
numblocks = 4;
}
if( 2000L > lrec.compressed_size)
{
sizeblock = lrec.compressed_size/2L;
numblocks = 2;
}
progresscount = 0L;
blockcount = 0;
PenPat(gray);
}
/* -------------------------------------------------------------------------- */
UpdateProgressWind(numblocks,blockcount)
int numblocks,blockcount;
{
Rect r;
/* if(blockcount > numblocks) blockcount = numblocks; */
SetRect(&r,(39+(blockcount-1)*340/numblocks),23,(39+blockcount*340/numblocks),39);
PaintRect(&r);
}
/* -------------------------------------------------------------------------- */
CloseProgressWind()
{
CloseWindow(wprogress);
}
/* -------------------------------------------------------------------------- */
Boolean check_abort()
{
EvQElPtr eq_p;
Boolean f_found=false;
eq_p = (EvQElPtr)(EventQueue.qHead);
while(true)
{
if((eq_p->evtQWhat==keyDown || eq_p->evtQWhat == autoKey) &&
(eq_p->evtQModifiers & cmdKey) && (eq_p->evtQMessage & charCodeMask) == '.')
{
Dequeue((QElemPtr)eq_p,&EventQueue);
f_found = true;
}
if(eq_p == (EvQElPtr)EventQueue.qTail) break;
eq_p = (EvQEl *)(eq_p->qLink);
}
return (f_found);
}
/* -------------------------------------------------------------------------- */
void set_file_time()
{
HFileInfo FiInfo;
unsigned char tfname[256];
OSErr result;
DateTimeRec dtr;
long seconds;
strcpy(tstring,filename);
CtoPstr(tstring);
memcpy(tfname,tstring,256);
FiInfo.ioNamePtr = tfname;
FiInfo.ioVRefNum = 0;
FiInfo.ioFVersNum = 0;
FiInfo.ioFDirIndex = 0;
result = PBGetFInfo(&FiInfo,false);
dtr.day = lrec.last_mod_file_date & 0x1F;
dtr.month = (lrec.last_mod_file_date >> 5) & 0x0F;
dtr.year = ((lrec.last_mod_file_date >> 9) & 0x7F) + 1980;
dtr.second = 0;
dtr.minute = (lrec.last_mod_file_time >> 5) & 0x3F;
dtr.hour = (lrec.last_mod_file_time >>11) & 0x1F;
dtr.second = 2*(lrec.last_mod_file_time & 0x1F);
Date2Secs(&dtr,&seconds);
FiInfo.ioFlCrDat = seconds;
FiInfo.ioFlMdDat = seconds;
result = PBSetFInfo(&FiInfo,false);
}
/* -------------------------------------------------------------------------- */
int create_output_file()
/* return non-0 if creat failed */
{
extern local_file_header lrec;
long freebytes;
int filerr;
freeSpaceOnVol(SFzipfd.vRefNum,&freebytes);
if(lrec.uncompressed_size > freebytes)
{
sprintf(tstring,"***********: %-12s -- no space on volume -- file skipped",filename);
DisplayString(CtoPstr(tstring));
return(1);
}
outfd = creat(filename, O_CREAT | O_RDWR | O_BINARY);
if (outfd == EOF)
{
sprintf(tstring,"***********: %-12s -- can't create output file -- file skipped",filename);
DisplayString(CtoPstr(tstring));
return(1);
}
strcpy(tstring,filename);
GetFInfo(CtoPstr(tstring),0,&ffinfo);
ffinfo.fdCreator = 'pZIP';
ffinfo.fdType = 'TEXT';
if((0L<zipoffset[dindex]) && (NULL==strstr(filename,".GIF")) && (NULL==strstr(filename,".gif"))) ffinfo.fdType='pBIN';
SetFInfo(tstring,0,&ffinfo);
/* write a single byte at EOF to pre-allocate the file */
lseek(outfd, lrec.uncompressed_size-1L, SEEK_SET);
filerr = write(outfd, "?", 1);
lseek(outfd, 0L, SEEK_SET);
return(0);
}
/* ------------------------------------------------------------------------- */
extract_member()
{
extern local_file_header lrec;
gifinfo gi;
char colors;
int ncolors;
long freebytes;
unsigned b;
FILE *in,*out;
int ch;
bits_left = 0;
bitbuf = 0;
incnt = 0;
outpos = 0L;
outcnt = 0;
outptr = outbuf;
zipeof = 0;
crc32val = 0xFFFFFFFFL;
/* create the output file with READ and WRITE permissions */
if(7>lrec.compression_method)
{
if (create_output_file())
{
DisplayLn();
SysBeep(1);
return(1);
}
}
switch (lrec.compression_method)
{
case 0: /* stored */
{
sprintf(tstring," Extracting: %-12s ", filename);
DisplayString(CtoPstr(tstring));
InitProgressWind("Extracting");
while (ReadByte(&b)) OUTB(b);
CloseProgressWind();
}
break;
case 1:
{
sprintf(tstring,"UnShrinking: %-12s ", filename);
DisplayString(CtoPstr(tstring));
InitProgressWind("UnShrinking");
unShrink();
CloseProgressWind();
}
break;
case 2:
case 3:
case 4:
case 5:
{
sprintf(tstring," Expanding: %-12s ",filename);
DisplayString(CtoPstr(tstring));
InitProgressWind("Expanding");
unReduce();
CloseProgressWind();
}
break;
case 6:
{
sprintf(tstring," Exploding: %-12s ",filename);
DisplayString(CtoPstr(tstring));
InitProgressWind("Exploding");
if(Explode()) return;
CloseProgressWind();
}
break;
default:
{
sprintf(tstring," : %-12s -- unknown compression method -- file skipped\015",filename);
DisplayString(CtoPstr(tstring));
}
}
if(6<lrec.compression_method) return;
/* write the last partial buffer, if any */
if (outcnt > 0)
{
UpdateCRC(outbuf, outcnt);
write(outfd, outbuf, outcnt);
}
crc32val = -1 - crc32val;
if (crc32val != lrec.crc32)
{
sprintf(tstring," -- Bad CRC %08lX (should be %08lX)", lrec.crc32, crc32val);
DisplayString(CtoPstr(tstring));
}
else DisplayString("\p -- successful");
/* if file ended in '.GIF' or '.gif' display additional GIF file info */
if((NULL!=strstr(filename,".GIF")) || (NULL!=strstr(filename,".gif")))
{
lseek(outfd,0L,0L);
read(outfd,tstring,sizeof(gifinfo));
memcpy(&gi,tstring,sizeof(gifinfo));
swap_bytes(&gi.screen_width);
swap_bytes(&gi.screen_height);
colors = gi.color_resolution & '\007';
ncolors = 1 << (1+(int) colors);
sprintf(tstring,"\015 -- GIF file: %dx%d %d colors",gi.screen_width,gi.screen_height,ncolors);
DisplayString(CtoPstr(tstring));
}
close(outfd);
/* strip linefeeds from text files if stripLFflag = true */
if (stripLFflag && (0>zipoffset[dindex]))
{
freeSpaceOnVol(SFzipfd.vRefNum,&freebytes);
if(lrec.uncompressed_size > freebytes)
{
DisplayString("\p\015 -- no space on volume for LF stripped file");
}
else
{
DisplayString("\p\015 -- stripping LF's ");
in = fopen(filename,"rb");
out = fopen("pZIPtemp01","wb");
if (out != NULL)
{
strcpy(tstring,"pZIPtemp01");
GetFInfo(CtoPstr(tstring),0,&ffinfo);
ffinfo.fdCreator = 'pZIP';
ffinfo.fdType = 'TEXT';
SetFInfo(tstring,0,&ffinfo);
outcnt = 0;
outptr = outbuf;
while ((ch=getc(in)) != EOF)
if('\012' != ch)
{
*outptr++ = ch;
if(++outcnt==out_size)
{
fwrite(outbuf,1,out_size,out);
outcnt = 0;
outptr = outbuf;
}
}
/* write the last partial buffer, if any */
if (outcnt > 0) fwrite (outbuf,1,outcnt,out);
fclose(in);
fclose(out);
remove(filename);
rename("pZIPtemp01",filename);
DisplayString("\p -- successful");
}
else
{
DisplayString("\p\015 -- error opening LF stripped file -- skipped");
}
}
}
/* set output file date and time */
set_file_time();
DisplayLn();
}
/* ------------------------------------------------------------------------- */
void process_local_file_header()
{
extern local_file_header lrec;
char temp[256];
read(zipfd, tstring, sizeof(lrec));
memcpy(&lrec,tstring,sizeof(lrec));
swap_bytes(&lrec.filename_length);
swap_bytes(&lrec.extra_field_length);
swap_lbytes(&lrec.compressed_size);
swap_lbytes(&lrec.uncompressed_size);
swap_bytes(&lrec.last_mod_file_time);
swap_bytes(&lrec.last_mod_file_date);
swap_bytes(&lrec.compression_method);
swap_bytes(&lrec.general_purpose_bit_flag);
swap_lbytes(&lrec.crc32);
get_string(lrec.filename_length, filename);
get_string(lrec.extra_field_length, extra);
if(TEXTfilterflag && (0L<zipoffset[dindex]) && (NULL==strstr(filename,".GIF")) && (NULL==strstr(filename,".gif"))) return;
if (choosefileflag)
{
strcpy(tstring,"Dearchive ╥");
strcat(tstring,filename);
strcat(tstring,"╙?");
ParamText(CtoPstr(tstring),"\p","\p","\p");
InitCursor();
if(1==Alert (102,nil))
{
c = GetCursor(watchCursor);
SetCursor(*c);
extract_member();
}
}
else extract_member();
}
/* -------------------------------------------------------------------------- */
long process_central_file_header()
{
central_directory_file_header rec;
char filename[STRSIZ];
char extra[STRSIZ];
char comment[STRSIZ];
static char *method[8]={" Stored"," Shrunk"," Reduced1"," Reduced2"," Reduced3"," Reduced4"," Imploded"," Unknown"};
static char *ny[2]={" no","yes"};
static char *mo[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
long offset;
int day,month,year,hour,minute,second;
if (dirflag)
{
memcpy(&rec,inbuf+incnt,sizeof(rec));
incnt = incnt + sizeof(rec);
}
else
{
read(zipfd,tstring,sizeof(rec));
memcpy(&rec,tstring,sizeof(rec));
}
swap_bytes(&rec.compression_method);
swap_lbytes(&rec.compressed_size);
swap_lbytes(&rec.uncompressed_size);
swap_bytes(&rec.last_mod_file_time);
swap_bytes(&rec.last_mod_file_date);
swap_lbytes(&rec.crc32);
swap_bytes(&rec.internal_file_attributes);
swap_bytes(&rec.filename_length);
swap_bytes(&rec.extra_field_length);
swap_bytes(&rec.file_comment_length);
swap_lbytes(&rec.relative_offset_local_header);
if (dirflag)
{
memcpy(filename,inbuf+incnt,rec.filename_length);
filename[rec.filename_length] = 0;
incnt = incnt + rec.filename_length;
memcpy(extra,inbuf+incnt,rec.extra_field_length);
extra[rec.extra_field_length] = 0;
incnt = incnt + rec.extra_field_length;
memcpy(comment,inbuf+incnt,rec.file_comment_length);
comment[rec.file_comment_length] = 0;
incnt = incnt + rec.file_comment_length;
}
else
{
get_string(rec.filename_length,filename);
get_string(rec.extra_field_length,extra);
get_string(rec.file_comment_length,comment);
}
if(6<rec.compression_method) rec.compression_method = 7;
day = rec.last_mod_file_date & 0x1F;
month = (rec.last_mod_file_date >> 5) & 0x0F;
year = ((rec.last_mod_file_date >> 9) & 0x7F) + 80;
hour = (rec.last_mod_file_time >>11) & 0x1F;
minute = (rec.last_mod_file_time >> 5) & 0x3F;
second = 2*(rec.last_mod_file_time & 0x1F);
sprintf(tstring,"%-12s%s%10ld %10ld%4d-%3s-%2d %02d:%02d:%02d %08lX %3s\015",
filename,
method[rec.compression_method],
rec.compressed_size,
rec.uncompressed_size,
day,
mo[month-1],
year,
hour,
minute,
second,
rec.crc32,
ny[rec.internal_file_attributes]);
DisplayString(CtoPstr(tstring));
offset = 1L + rec.relative_offset_local_header;
if (1==rec.internal_file_attributes) offset = -offset;
return(offset);
}
/* ------------------------------------------------------------------------- */
int process_end_central_dir()
{
end_central_dir_record rec;
Rect drect;
memcpy(&rec,inbuf+incnt+1,sizeof(rec));
incnt = incnt + 1 + sizeof(rec);
swap_bytes(&rec.total_entries_central_dir);
swap_lbytes(&rec.offset_start_central_directory);
swap_bytes(&rec.zipfile_comment_length);
wlistflag = true;
wlist = GetNewDWindow(101,-1L);
SetWTitle(wlist,&SFzipfd.fName);
SetDWindowStyle(wlist,150,9,1,0);
DisplayText(inbuf+incnt,(long) rec.zipfile_comment_length);
if(fpos < rec.offset_start_central_directory)
{
dirflag = true;
incnt = rec.offset_start_central_directory - fpos;
}
else
{
dirflag = false;
lseek(zipfd,rec.offset_start_central_directory,0);
}
return(rec.total_entries_central_dir);
}
/* ------------------------------------------------------------------------- */
/*long labs(x)
long x;
{
long y;
y = x;
if(0L>y) y = -y;
return(y);
}*/
/* ------------------------------------------------------------------------- */
void process_headers()
{
longint sig;
Boolean abortflag=false;
if(finishedflag)
{
SysBeep(1);
strcpy(tstring,"\015ZIP file extraction completed for this file!");
ParamText(CtoPstr(tstring),"\p","\p","\p");
HiliteMenu(nil);
(void) StopAlert(101,nil);
return;
}
c = GetCursor(watchCursor);
SetCursor(*c);
for (dindex=0;dindex<direntries;dindex++)
{
lseek(zipfd,labs(zipoffset[dindex])-1,0);
read(zipfd, tstring, sizeof(sig));
memcpy(&sig,tstring,sizeof(sig));
if (sig != LOCAL_FILE_HEADER_SIGNATURE)
{
DisplayString("\pBad ZIP file local header signature--file skipped\015");
}
else process_local_file_header();
if(abortflag = check_abort())
{
DisplayString("\p\r * PROCESSING ABORTED *\r");
ParamText("\p\rProcessing aborted!","\p","\p","\p");
break;
}
}
if(!abortflag) ParamText("\p\rZIP file extraction completed!","\p","\p","\p");
InitCursor();
close(zipfd);
finishedflag = true;
Delay(20L,sig);
SysBeep(1);
Delay(5L,sig);
SysBeep(1);
HiliteMenu(nil);
(void) NoteAlert (101,nil);
}
/* ------------------------------------------------------------------------- */
AllocateBuffers()
{
int buffer_fail = 0;
extern int *Prefix_of;
extern byte *Suffix_of;
extern byte *Stack;
int i;
Prefix_of = calloc(hsize+1,2);
Suffix_of = calloc(hsize+1,1);
Stack = calloc(hsize+1,1);
/* allocate i/o buffers */
inbuf = (char *) (malloc(INBUFSIZ));
outbuf = (char *) (malloc(OUTBUFSIZ));
in_size = INBUFSIZ;
out_size = OUTBUFSIZ;
if ((inbuf == NULL) || (outbuf == NULL))
{
ParamText("\pInsufficient memory to allocate buffers!","\p","\p","\p");
(void) StopAlert (101,nil);
SkelWhoa();
}
}
/* ------------------------------------------------------------------------- */
aboutUnZip()
{
(void) Alert(100,nil);
}
/* ------------------------------------------------------------------------- */
setLFflag()
{
if (!stripLFflag)
{
stripLFflag = true;
CheckItem(mOptions,3,true);
mstrip = NewMenu(5,"\p*Strip LF on*");
SkelMenu(mstrip,nil,nil);
}
else
{
stripLFflag = false;
CheckItem(mOptions,3,false);
mstrip = NewMenu(5,"\p");
SkelMenu(mstrip,nil,nil);
}
}
/* ------------------------------------------------------------------------- */
setTEXTfilterflag()
{
if (!TEXTfilterflag)
{
TEXTfilterflag = true;
CheckItem(mOptions,4,true);
mfilter = NewMenu(4,"\p*.GIF & TEXT filter*");
SkelMenu(mfilter,nil,nil);
}
else
{
TEXTfilterflag = false;
CheckItem(mOptions,4,false);
mfilter = NewMenu(4,"\p");
SkelMenu(mfilter,nil,nil);
}
}
/* ------------------------------------------------------------------------- */
setchoosefileflag()
{
if (!choosefileflag)
{
choosefileflag = true;
CheckItem(mOptions,5,true);
}
else
{
choosefileflag = false;
CheckItem(mOptions,5,false);
}
}
/* ------------------------------------------------------------------------- */
openfile()
{
extern int direntries;
extern long fpos;
long sig;
long flength;
long temp;
int tbufsize;
boolean foundecdflag;
DisableItem(mOptions,1);
if(wlistflag)
{
if (!finishedflag) close(zipfd);
SkelRmveWind(wlist);
wlistflag = false;
}
finishedflag = false;
SFGetFile(bloc,"\p",nil,-1,nil,nil,&SFzipfd);
if(!SFzipfd.good) return;
else SetVol("\p",SFzipfd.vRefNum);
c = GetCursor(watchCursor);
SetCursor(*c);
memcpy(tstring,&SFzipfd.fName,64);
zipfd = open(PtoCstr(tstring), O_RDONLY | O_BINARY);
flength = lseek(zipfd,0L,2);
fpos = flength - 8192;
tbufsize = 8192;
if (0 > fpos)
{
fpos = 0;
tbufsize = flength;
}
lseek(zipfd,-(long) tbufsize,2);
read(zipfd,inbuf,tbufsize);
foundecdflag = false;
for (incnt=tbufsize-18; incnt>4; incnt--)
{
if (('\006'== *(inbuf + (long) incnt )) &&
('\005'== *(inbuf + (long) (incnt-1) )) &&
( 'K'== *(inbuf + (long) (incnt-2) )) &&
( 'P'== *(inbuf + (long) (incnt-3) )))
{
foundecdflag = true;
break;
}
}
if (!foundecdflag)
{
/* not a ZIP file alert */
memcpy(tstring,&SFzipfd.fName,64);
PtoCstr(tstring);
strcat(tstring,"\015\015Not a ZIP file!");
ParamText(CtoPstr(tstring),"\p","\p","\p");
InitCursor();
SysBeep(1);
HiliteMenu(nil);
(void) StopAlert (101,nil);
close(zipfd);
return;
}
direntries = process_end_central_dir();
DisplayString("\p\015\015File Name Method Size Now Full Size Date Time CRC Text\015");
DisplayString("\p--------- -------- -------- --------- --------- -------- -------- ----\015");
for (dindex=0;dindex<direntries;dindex++)
{
if (dirflag)
{
memcpy(&sig,inbuf+incnt,sizeof(sig));
incnt = incnt + sizeof(sig);
}
else
{
read(zipfd,tstring,sizeof(sig));
memcpy(&sig,tstring,sizeof(sig));
}
if (sig == CENTRAL_FILE_HEADER_SIGNATURE) zipoffset[dindex]=process_central_file_header();
}
DisplayLn();
InitCursor();
EnableItem(mOptions,1);
SysBeep(6);
SetDWindowPos(wlist,0);
ShowWindow(wlist);
}
/* ------------------------------------------------------------------------- */
DoFileMenu(item)
int item;
{
switch(item)
{
case 1: openfile(); break;
case 2: {
free(Prefix_of);
free(Suffix_of);
free(Stack);
free(inbuf);
free(outbuf);
SkelWhoa();
break;
}
}
}
/* ------------------------------------------------------------------------- */
DoOptionsMenu(item)
int item;
{
switch(item)
{
case 1: process_headers(); break;
case 2: break;
case 3: setLFflag(); break;
case 4: setTEXTfilterflag();break;
case 5: setchoosefileflag(); break;
}
}
/* ------------------------------------------------------------------------- */
void main()
{
SkelInit(6,nil);
SkelApple("\pAbout UnZip 1.02c╔",aboutUnZip);
mFile = GetMenu(101);
(void) SkelMenu(mFile,DoFileMenu,nil,false);
mOptions = GetMenu(102);
(void) SkelMenu(mOptions,DoOptionsMenu,nil,true);
AllocateBuffers();
SkelMain();
SkelClobber();
}